package tarena.netctoss.dao.impl;

import java.sql.SQLException;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.HibernateTemplate;

import tarena.netctoss.dao.Pagination;
import tarena.netctoss.dao.PricingCondition;
import tarena.netctoss.dao.PricingDao;
import tarena.netctoss.po.Pricing;

/**
 * 资费模块数据库访问实现类
 * 
 * @author Wangpeihu
 * @team [Never give up]
 * @since JDK1.6(建议)
 * @date 2010-3-2
 */
public class PricingDaoImpl implements PricingDao {

	/** hibernate模板 */
	private HibernateTemplate hibernateTemplate;

	/**
	 * 依赖注入hibernate模板
	 * 
	 * @param hibernateTemplate
	 */
	public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
		this.hibernateTemplate = hibernateTemplate;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see tarena.netctoss.dao.PricingDao#delete(tarena.netctoss.po.Pricing)
	 */
	public void delete(Pricing pricing) {
		hibernateTemplate.delete(pricing);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see tarena.netctoss.dao.PricingDao#findAll()
	 */
	@SuppressWarnings("unchecked")
	public List<Pricing> findAll() {
		return hibernateTemplate.find("from Pricing p order by p.name");
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * tarena.netctoss.dao.PricingDao#findAll(tarena.netctoss.dao.Pagination)
	 */
	@SuppressWarnings("unchecked")
	public List<Pricing> findAll(final Pagination page) {
		return hibernateTemplate.executeFind(new HibernateCallback() {
			public Object doInHibernate(Session session)
					throws HibernateException, SQLException {
				Query q = session.createQuery("from Pricing p order by p.name");
				q.setFirstResult((page.getPage() - 1) * page.getPageSize());
				q.setMaxResults(page.getPageSize());
				return q.list();
			}
		});
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * tarena.netctoss.dao.PricingDao#findAll(tarena.netctoss.dao.Pagination,
	 * tarena.netctoss.dao.PricingCondition)
	 */
	@SuppressWarnings("unchecked")
	public List<Pricing> findAll(final Pagination page,
			final PricingCondition pc) {
		return hibernateTemplate.executeFind(new HibernateCallback() {
			public Object doInHibernate(Session session)
					throws HibernateException, SQLException {
				Criteria c = getCriteria(pc, session);
				c.setFirstResult((page.getPage() - 1) * page.getPageSize());
				c.setMaxResults(page.getPageSize());
				return c.list();
			}
		});
	}

	/**
	 * 创建一个Criteria
	 * 
	 * @param pc
	 * @param session
	 * @return
	 */
	private Criteria getCriteria(final PricingCondition pc, Session session) {
		Criteria c = session.createCriteria(Pricing.class);
		// 如果存在下列条件

		if (null != pc.getName() && !"".equals(pc.getName())) {
			// where p.name like '%abcabc%'
			c.add(Restrictions.like("name", "%" + pc.getName() + "%"));
		}
		if (pc.getBaseFeeMin() > 0) {
			// p.basefee >= ...
			c.add(Restrictions.ge("basefee", pc.getBaseFeeMin()));
		}
		if (pc.getBaseFeeMax() > 0) {
			// p.basefee <= ...
			c.add(Restrictions.le("basefee", pc.getBaseFeeMax()));
		}
		if (pc.getRateFeeMin() > 0) {
			// p.ratefee >= ...
			c.add(Restrictions.ge("ratefee", pc.getRateFeeMin()));
		}
		if (pc.getRateFeeMax() > 0) {
			// p.ratefee <= ...
			c.add(Restrictions.le("ratefee", pc.getRateFeeMax()));
		}
		return c;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see tarena.netctoss.dao.PricingDao#findById(java.lang.Integer)
	 */
	public Pricing findById(Integer id) {
		return (Pricing) hibernateTemplate.get(Pricing.class, id);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see tarena.netctoss.dao.PricingDao#save(tarena.netctoss.po.Pricing)
	 */
	public void save(Pricing pricing) {
		hibernateTemplate.save(pricing);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see tarena.netctoss.dao.PricingDao#update(tarena.netctoss.po.Pricing)
	 */
	public void update(Pricing pricing) {
		hibernateTemplate.update(pricing);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * tarena.netctoss.dao.PricingDao#loadMaxPage(tarena.netctoss.dao.Pagination
	 * , tarena.netctoss.dao.PricingCondition)
	 */
	public void loadMaxPage(final Pagination page, final PricingCondition pc) {
		hibernateTemplate.execute(new HibernateCallback() {
			public Object doInHibernate(Session session)
					throws HibernateException, SQLException {
				Criteria c = getCriteria(pc, session);
				// 添加多行函数查询
				// select count(*) from Pricing where name like ....
				c.setProjection(Projections.rowCount());
				Object o = c.uniqueResult();
				// hibernate 低版本count(*)返回 Integer
				// hibernate 高版本count(*)返回 Long
				int rowCount = 0;
				if (o instanceof Long) {
					rowCount = ((Long) o).intValue();
				} else {
					rowCount = ((Integer) o).intValue();
				}
				int maxPage = (rowCount + page.getPageSize() - 1)
						/ page.getPageSize();
				page.setMaxPage(maxPage);
				return null;
			}
		});
	}

}
